"""
服务端
"""
import socket
import time
from threading import Thread, Lock

lock = Lock()

nickname_list = []  # 在线用户昵称列表
conn_list = []  # 连接列表
msg_list = []  # 消息列表

IP_PORT = ('0.0.0.0', 8000)  # 服务器IP+端口 端口必须开放
s = socket.socket()
s.bind(IP_PORT)
s.listen(100)  # 半连接池设置为100


def msg_print():
    """消息打印"""
    while True:
        if msg_list:
            print('---', msg_list)
            for conn in conn_list:
                conn.send(msg_list[0].encode('utf8'))
            with lock:
                msg_list.pop(0)


def user_connect(conn):
    # 昵称校验
    while True:
        nickname = conn.recv(1024).decode('utf8')
        print(nickname)
        if nickname in nickname_list:
            conn.send('此昵称已存在！'.encode('utf8'))
            continue
        # 昵称、链接、登录消息添加
        with lock:
            nickname_list.append(nickname)
            msg_list.append(f'昵称[{nickname}]加入聊天！')
            conn_list.append(conn)
        break

    # 聊天循环
    while True:
        try:
            msg = conn.recv(1024).decode('utf8')

        except ConnectionResetError as e:
            print(e)
            with lock:
                # 昵称、链接、登录消息删除
                nickname_list.remove(nickname)
                msg_list.append(f'昵称[{nickname}]离开聊天室！')
                conn_list.remove(conn)
                break

        with lock:
            msg_list.append(msg)

        if len(msg) == 0:  # 防止断开连接时发生死循环
            break

        print(f'收到: {msg}')

    # 昵称、链接、登录消息删除
    if nickname in nickname_list:
        with lock:
            nickname_list.remove(nickname)
            msg_list.append(f'昵称[{nickname}]离开聊天室！')
            conn_list.remove(conn)

        conn.close()


if __name__ == '__main__':
    Thread(target=msg_print).start()
    while True:
        conn, addr = s.accept()
        Thread(target=user_connect, args=(conn,)).start()
